"""FastAPI application factory with global middleware and routers."""

from __future__ import annotations

import asyncio
import logging
from contextlib import asynccontextmanager
from typing import AsyncGenerator

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

from ..api.v1.api import api_router
from .config import settings
from .errors import (
    http_exception_handler,
    server_error_handler,
    validation_exception_handler,
)

logger = logging.getLogger(__name__)


@asynccontextmanager
async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
    """Application lifespan manager - handles startup/shutdown events."""
    # Startup: initialize singletons and warmup cache
    logger.info("🚀 Application startup: initializing services...")

    scheduler = None
    try:
        from ..db.session import SessionLocal
        from ..services.ai_extraction_service import AIExtractionService
        from ..services.ai_tag_engine import HybridTagEngine
        from ..services.cache_warmup_service import CacheWarmupService
        from ..scheduler import start_scheduler

        # 初始化AI服务单例并存储到app.state
        qwen_key = settings.QWEN_API_KEY or settings.DASHSCOPE_API_KEY
        hunyuan_id = getattr(settings, "HUNYUAN_SECRET_ID", None)
        hunyuan_key = getattr(settings, "HUNYUAN_SECRET_KEY", None)

        if qwen_key or (hunyuan_id and hunyuan_key):
            app.state.ai_engine = HybridTagEngine(
                qwen_api_key=qwen_key,
                hunyuan_secret_id=hunyuan_id,
                hunyuan_secret_key=hunyuan_key,
                cache_size=2000,
            )
            logger.info("✅ AI Engine initialized in application state")
        else:
            app.state.ai_engine = None
            logger.warning("⚠️ AI Engine not initialized - no API keys configured")

        # 初始化AI提取服务单例
        app.state.ai_extraction_service = AIExtractionService(qwen_api_key=qwen_key)
        logger.info("✅ AI Extraction Service initialized in application state")

        # 执行缓存预热
        warmup_service = CacheWarmupService(app.state.ai_extraction_service)
        db = SessionLocal()
        try:
            await warmup_service.warmup_property_cache(db, batch_size=50)
            logger.info("✅ Cache warmup completed successfully")
        finally:
            db.close()

        # 启动定时任务调度器
        scheduler = start_scheduler()
        app.state.scheduler = scheduler
        logger.info("✅ Background scheduler started")

    except Exception as e:
        logger.error(f"❌ Startup initialization failed: {e}")
        # 不阻止应用启动

    yield  # Application is running

    # Shutdown: cleanup
    logger.info("🛑 Application shutdown - cleaning up resources")
    if hasattr(app.state, "ai_engine"):
        delattr(app.state, "ai_engine")
    if hasattr(app.state, "ai_extraction_service"):
        delattr(app.state, "ai_extraction_service")
    if scheduler:
        scheduler.shutdown()
        logger.info("✅ Scheduler shutdown completed")


def create_app() -> FastAPI:
    app = FastAPI(
        lifespan=lifespan,
        title=settings.APP_NAME,
        description="""
## 房产CRM管理系统 API

AI驱动的房产客户关系管理平台，提供完整的客户、房源、访客单管理功能。

### 核心功能模块

- **客户管理**: 客户信息CRUD、AI标签提取、需求分类
- **房源管理**: 房源台账、状态跟踪、价格管理
- **访客单管理**: 带看记录、满意度评分、意向度跟踪
- **Excel导入**: 批量数据导入、智能列映射
- **数据统计**: 满意度统计、业绩分析

### 技术栈

- FastAPI 0.115.2 + SQLAlchemy 2.0.36
- Pydantic 2.10.3 数据验证
- SQLite3 (开发) / MySQL (生产)
- AI标签引擎: LRU缓存 + Qwen3
        """,
        version="1.0.0",
        openapi_url=f"{settings.API_V1_STR}/openapi.json",
        docs_url="/docs",
        redoc_url="/redoc",
        openapi_tags=[
            {"name": "auth", "description": "认证与授权"},
            {"name": "properties", "description": "房源管理"},
            {"name": "visitor-sheets", "description": "访客单管理"},
            {"name": "leads", "description": "客户管理"},
            {"name": "imports", "description": "Excel导入"},
            {"name": "performance", "description": "绩效管理"},
            {"name": "stats", "description": "数据统计"},
        ],
    )

    app.include_router(api_router, prefix=settings.API_V1_STR)

    # CORS: 简单兼容处理，不固定前端端口
    # 优先使用环境变量指定的允许来源；否则使用配置的正则或默认正则
    if settings.BACKEND_CORS_ORIGINS:
        # Convert AnyHttpUrl to string and remove trailing slash for exact matching
        origins = [str(o).rstrip("/") for o in settings.BACKEND_CORS_ORIGINS]
        app.add_middleware(
            CORSMiddleware,
            allow_origins=origins,
            allow_credentials=True,
            allow_methods=["*"],
            allow_headers=["*"],
        )
    else:
        # 使用配置的正则或默认的localhost正则
        cors_regex = settings.CORS_ORIGIN_REGEX or r"^https?://(localhost|127\\.0\\.0\\.1)(:\\d+)?$"
        logger.info(f"Using CORS origin regex: {cors_regex}")
        app.add_middleware(
            CORSMiddleware,
            allow_origin_regex=cors_regex,
            allow_credentials=True,
            allow_methods=["*"],
            allow_headers=["*"],
        )

    app.add_exception_handler(Exception, server_error_handler)
    from fastapi import HTTPException
    from fastapi.exceptions import RequestValidationError
    from starlette.exceptions import HTTPException as StarletteHTTPException

    app.add_exception_handler(HTTPException, http_exception_handler)  # type: ignore[arg-type]
    app.add_exception_handler(StarletteHTTPException, http_exception_handler)  # type: ignore[arg-type]
    app.add_exception_handler(RequestValidationError, validation_exception_handler)  # type: ignore[arg-type]

    return app
